package com.example.comm.comm;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 查询显示页面数据类,用来存放分页查询中每一页的数据.
 * <p>
 * 页面数据类用来存放查询翻页过程中的数据，里面存放指定条数的数据，数据中包含哪了结果集中的部分数据。<br>
 * 页面数据类中包含数据信息以及页面属性信息,其中包括开始的记录数和总记录数,页面大小等信息.
 * 
 * @author fengwh
 * @version 1.0 增加了默认的构造器，可以在spring中创建等
 * @see Page 从com.inspur.common..Page类迁移而来
 */

public class Page<O> implements Serializable {

	public static int DEFAULTPAGESIZE = 20;

	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unchecked")
	public static final Page EMPTY_PAGE = new Page(Collections.EMPTY_LIST, 0,
			0, 0);

	// 结果数据列表
	private List<O> resultList = null;

	// 页面开始记录数
	private int start = 0;

	// 结果总记录数，如果是-1的话，表示不知道具体有多少页
	private int totalSize = -1;

	// 页面数据大小.
	private int pageSize = DEFAULTPAGESIZE;

	/**
	 * 当不存在总数时，以跳转的方式展示页数，可以向后跳转的最大页数
	 */
	private int nextMax = 7;
	/**
	 * 当不存在总数时，以跳转的方式展示页数，可以向前跳转的最大页数
	 */
	private int previousMax = 3;

	/**
	 * 一个数据记录大小为20，但无数据的分页对象，一般是初始化时使用
	 */
	public Page() {
		this(null, 0, DEFAULTPAGESIZE, -1);
	}

	/**
	 * 通过给定的参数构建页面数据对象.
	 * 
	 * @param resultList
	 *            结果集数据列表
	 * @param start
	 *            数据集中第一个数据对象的编号．
	 * @param totalSize
	 *            总的数据记录数
	 * @param pageSize
	 *            页面数据大小
	 */
	public Page(List<O> resultList, int start, int pageSize, int totalSize) {
		setResultList(resultList);
		setStart(start);
		setPageSize(pageSize);
		setTotalSize(totalSize);
	}

	/**
	 * 是否是不知道有多少条记录，即没有获取到数据记录总数
	 * 
	 * @return true：是；false：否
	 */
	public boolean isUnknownCount() {
		return totalSize == -1;
	}

	/**
	 * 构造数据记录总数，主要是不知道总数时，可以根据一些动态的信息判断是否已经确定了总数
	 */
	public void buildTotalSize() {
		if (isUnknownCount()) {
			if (getResultList().size() < getPageSize()) {
				setTotalSize(getStart() + getResultList().size());
			}
		}
	}

	/**
	 * 当记录总数大于零时才认为是已经知道了记录总数<br>
	 * 注：零可能是不知道数量（因为默认值为零），也可能是获取的数量本身就是零（无数据）。
	 * 
	 * @return
	 */
	public boolean hasKnownTotalCount() {
		return totalSize > 0;
	}

	/**
	 * 以跳转的方式展示页数时，获取跳转的第一页页号
	 * 
	 * @return
	 */
	public int getFirstPageNumber() {
		if (getCurPageNum() > getPreviousMax()) {
			return getCurPageNum() - getPreviousMax();
		}
		return 1;
	}

	/**
	 * 以跳转的方式展示页数时，获取跳转的最后页页号
	 * 
	 * @return
	 */
	public int getLastPageNumber() {
		if (isUnknownCount()
				|| (getPageCount() - getCurPageNum() > getNextMax())) {
			return getCurPageNum() + getNextMax();
		}
		return getPageCount();
	}

	/**
	 * 当前页面对象是否存在下一个页面对象.
	 * 
	 * @return boolean 是否存在下一个页面对象
	 */
	public boolean hasNextPage() {
		if (isUnknownCount())
			return true;
		return (start + resultList.size()) < getTotalSize();
	}

	/**
	 * 当前页面对象是否存在前一个页面对象.
	 * 
	 * @return boolean 是否存在前一个页面对象
	 */
	public boolean hasPreviousPage() {
		return start > 0;
	}

	/**
	 * 当前页面对象的下一个页面对象的数据记录编号.
	 * 
	 * @return int 下一个页面对象的数据记录编号.
	 */
	public int getStartOfNextPage() {
		return start + resultList.size();
	}

	/**
	 * 取得当前页面对象的前一个对象页数.
	 * 
	 * @return int 前一个对象页数
	 */
	public int getStartOfPreviousPage() {
		return Math.max(start - pageSize, 0);
	}

	/**
	 * 取得总页数.
	 * 
	 * @return int 总页数
	 */
	public int getPageCount() {
		int ret = 0;
		if (pageSize > 0) {
			if (isUnknownCount()) {
				return getTotalSize();
			}
			if (getTotalSize() % pageSize == 0) {
				ret = getTotalSize() / pageSize;
			} else {
				ret = getTotalSize() / pageSize + 1;
			}

		}

		return ret;
	}

	/**
	 * 取得当前页数.
	 * 
	 * @return int 当前页数
	 */
	public int getCurPageNum() {
		int ret = 0;
		if (pageSize > 0)
			ret = start / pageSize + 1;
		return ret;
	}

	/**
	 * 取得当前页数对象的数据列表的数据大小.
	 * 
	 * @return int 数据大小
	 */
	public int getSize() {
		return resultList.size();
	}

	/**
	 * 取得页面数据的大小.
	 * 
	 * @return int 页数
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * 设置页面数据的大小.
	 * 
	 * @param pageSize
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * 取得当前页面数据中的数据列表．
	 * 
	 * @return List 数据列表
	 */
	public List<O> getResultList() {
		return resultList;
	}

	/**
	 * 设置数据对象中的数据列表．
	 * 
	 * @param resultList
	 */
	public void setResultList(List<O> resultList) {
		if (resultList == null) {
			this.resultList = new ArrayList<O>();
		} else {
			this.resultList = resultList;
		}
	}

	/**
	 * 取得当前页数据对象的第一个数据的编号．
	 * 
	 * @return int 第一个数据的编号
	 */
	public int getStart() {
		return start;
	}

	/**
	 * 设置当前页数据对象的第一个对象的数据的编号．
	 * 
	 * @param start
	 */
	public void setStart(int start) {
		this.start = start;
	}

	/**
	 * 取得所有数据的总记录数．
	 * 
	 * @return int 所有数据的总记录数
	 */
	public int getTotalSize() {
		return totalSize;
	}

	/**
	 * 设置数据的总记录数．
	 * 
	 * @param totalSize
	 */
	public void setTotalSize(int totalSize) {
		this.totalSize = totalSize;
	}

	public String toString() {
		return "{" + "start:" + getStart() + ",totalSize:" + getTotalSize()
				+ ",pageSize:" + getPageSize() + ",resultList:"
				+ getResultList() + "}";
	}

	public int getNextMax() {
		return nextMax;
	}

	public void setNextMax(int nextMax) {
		this.nextMax = nextMax;
	}

	public int getPreviousMax() {
		return previousMax;
	}

	public void setPreviousMax(int previousMax) {
		this.previousMax = previousMax;
	}

	public void clear() {
		if (resultList != null) {
			resultList.clear();
		}
		setTotalSize(0);
	}
}
